package com.zhang.service;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.zhang.async.EmailService;
import com.zhang.common.Constant;
import com.zhang.entity.UserInfo;
import com.zhang.entity.response.ResponseResult;
import com.zhang.entity.response.ResultCode;
import com.zhang.entity.vo.LoginBody;
import com.zhang.entity.vo.RegisterBody;
import com.zhang.entity.vo.ResetPasswordBody;
import com.zhang.exception.ServiceException;
import com.zhang.mapper.UserInfoMapper;
import com.zhang.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;

import static com.zhang.common.Constant.*;

/**
 * Created with IntelliJ IDEA.
 * User: 张
 * Date: 2024-10-28
 * Time: 17:51
 * Description:
 */
@Service
public class UserInfoService {

    @Value("${zhang.security.private_key}")
    private String private_key;
    @Value("${zhang.email.time_out}")
    private int timeOut;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private AuthorityService authorityService;
    @Autowired
    private EmailService emailService;
    @Autowired
    private RedisUtil redisUtil;

    public Boolean doLogin(LoginBody form) {
        if (StrUtil.hasBlank(form.getAccount(), form.getPassword())) {
            throw new ServiceException("用户名/密码必须填写");
        }
        UserInfo user = userInfoMapper.getUserInfoByUserAccount(form.getAccount(),USER_STATE_NORMAL);
        if (user == null) {
            return null;
        }
        if (form.getPassword().equals(SaSecureUtil.aesDecrypt(private_key, user.getPassword()))) {
            StpUtil.login(user.getId(),
                    SaLoginConfig.setExtra("userName", user.getUserName()));
            return true;
        }
        return false;
    }

    public void register(RegisterBody registerBody) {
        if (StrUtil.hasBlank(registerBody.getUserName(), registerBody.getPassword())) {
            throw new ServiceException("用户名/密码必须填写");
        }
        if (registerBody.getUserName().length() < Constant.USERNAME_MIN_LENGTH
                || registerBody.getUserName().length() > Constant.USERNAME_MAX_LENGTH) {
            throw new ServiceException("账户长度必须在2到20个字符之间");
        }
        if (registerBody.getPassword().length() < Constant.PASSWORD_MIN_LENGTH
                || registerBody.getPassword().length() > Constant.PASSWORD_MAX_LENGTH) {
            throw new ServiceException("密码长度必须在5到20个字符之间");
        }
        // 判断账号是否已存在
        if (userInfoMapper.getUserInfoByUserAccount(registerBody.getPhone(),USER_STATE_NORMAL) != null) {
            throw new ServiceException("手机号已存在");
        }

        UserInfo user = new UserInfo();
        user.setId(USER_DEFAULT_ID)
                .setUserName(registerBody.getUserName())
                .setPassword(SaSecureUtil.aesEncrypt(private_key, registerBody.getPassword()))
                .setPhone(registerBody.getPhone())
                .setImageId(IMAGE_DEFAULT)
                .setEmail(registerBody.getEmail())
                .setAuthority(AUTHORITY_DEFAULT)
                .setCreateTime(new Date())
                .setUserState(USER_STATE_NORMAL);
        // 注册用户
        userInfoMapper.registerUser(user);
        // 添加默认user权限
        authorityService.addAuthority(user.getId(),AUTHORITY_DEFAULT);
    }

    public ResponseResult<String> sendVerificationCode(String phone) {
        // 生成验证码
        String code = String.valueOf((int) ((Math.random() * 9 + 1) * 100000));
        //  redis保存验证码
        redisUtil.set("code:"+phone,code,timeOut);
        String email = userInfoMapper.getEmailByPhone(phone, USER_STATE_NORMAL);
        if (email == null){
            return ResponseResult.error("该手机号未注册");
        }
        // 发送验证码
        emailService.sendEmail(email,code);
        return ResponseResult.success();
    }

    public ResultCode resetPassword(ResetPasswordBody resetPasswordBody){
        String value = (String)redisUtil.get("code:"+resetPasswordBody.getPhone());
        if (value == null){
            throw new ServiceException("验证码已过期");
        }
        if (!value.equalsIgnoreCase(resetPasswordBody.getCode())){
            throw new ServiceException("验证码错误");
        }
        if (resetPasswordBody.getPassword().length() < Constant.PASSWORD_MIN_LENGTH
                || resetPasswordBody.getPassword().length() > Constant.PASSWORD_MAX_LENGTH) {
            throw new ServiceException("密码长度必须在5到20个字符之间");
        }
        userInfoMapper.updatePasswordByPhone(resetPasswordBody.getPhone(),
                SaSecureUtil.aesEncrypt(private_key,resetPasswordBody.getPassword()));
        return ResultCode.SUCCESS;
    }
}
